//
// Created by 20692 on 2022/5/19.
//

#ifndef PROCESSSIMULATION_DATASTRUCTURE_H
#define PROCESSSIMULATION_DATASTRUCTURE_H

// 进程
typedef struct semaphore {
    int value; // 信号量
    struct status *run, *wait, *block; // 运行，就绪，堵塞队列
} Semaphore;

// 进程状态
typedef struct status {
    int cap;
    int len;
    char *name; // 队列名称
    struct node *head;
    struct node *tail;
} Status;

// 产品
typedef struct node {
    char *content;
    struct node *next;
} Node;

Node *NewNode(char *content) {
    Node *n = (Node *) malloc(sizeof(Node));
    n->content = content;
    n->next = NULL;
    return n;
}

Status *NewStatus(int cap, char *name) {
    Status *S = (Status *) malloc(sizeof(Status));;
    S->cap = cap;
    S->len = 0;
    S->name = name;
    S->head = NULL;
    S->tail = NULL;
    return S;
}

Semaphore *NewSemaphore(int value) {
    Semaphore *S = (Semaphore *) malloc(sizeof(Semaphore));
    S->value = value;
    S->run = NewStatus(20, "run");
    S->wait = NewStatus(20, "wait");
    S->block = NewStatus(20, "block");
    return S;
}

void Push(Status *S, char *content) {
    if (S->cap == S->len) {
        printf("Status %s queue is full\n", S->name);
        return;
    } else if (content == NULL || strcmp(content, "") == 0) {
        printf("Status %s queue, the content is empty, not push\n", S->name);
        return;
    }

    Node *node = (Node *) malloc(sizeof(Node));
    node->content = content;
    node->next = NULL;
    if (S->len == 0) {
        S->head = node;
        S->tail = node;
        S->len++;
        return;
    }
    S->tail->next = node;
    S->tail = node;
    S->len++;
}

Node *Pop(Status *S) {
    Node *n = (Node *) malloc(sizeof(Node));
    n->content = "";
    if (S->len == 0) {
        printf("Status %s queue is empty\n", S->name);
        return n;
    }
    n = S->head;
    S->head = S->head->next;
    S->len--;
    return n;
}

Node *Top(Status *S) {
    if (S->len == 0) {
        printf("Status %s队列 为空\n", S->name);
        return NULL;
    }
    Node *p = (Node *) malloc(sizeof(Node));
    p = S->head;
    return p;
}

void Print(Status *S) {
    // printf("%s: ", S->name);
    if (S == NULL || S->len == 0) {
        printf("%-25s", "none");
        return;
    }

    char str[20] = {0};
    Node *p = S->head;
    while (p != NULL) {
        strcat(str, p->content);
        strcat(str, " ");
        p = p->next;
    }
    printf("%-25s", str);
}

#endif //PROCESSSIMULATION_DATASTRUCTURE_H
